import Vue from 'vue';
import { getToken } from "@/config/auth";
import { Validate } from '@/config/validate';
import store from '@/store';
import { API_URL } from "@/config/constant";
import JSONbig from 'json-bigint';

// 创建 BigInt 处理实例（大数字转为字符串避免精度丢失）
const JSONbigParser = JSONbig({ storeAsString: true });

const API_TIMESTAMP = Object.create(null);
let timer = null;

const request = (config) => {
    return new Promise(function (resolve, reject) {
        let { url, method = 'GET', data, period, ignoreError } = config;
        let token = getToken();
        let header = {};
        header['pb-token'] = token;
        let timestamp;

        if (Validate.isEmpty(data)) {
            data = {};
        }

        // 请求竞态处理
        if (period) {
            if (period === true) period = 200;
            let now = Date.now();
            if (now - API_TIMESTAMP[url] < period) {
                return console.log(`单位时间${period}ms内重复请求，已被拦截，url：${url}`);
            }
            timestamp = API_TIMESTAMP[url] = now;
        }
        console.log('请求参数：',data);

        uni.request({
            url: API_URL + url,
            method: method,
            data: data || {},
            header: header,
            dataType:'text',
            complete: (res) => {
                // 处理可能的大整数JSON解析
                try {
                    res.data = JSONbigParser.parse(res.data);

                } catch (e) {
                    console.error('JSON解析失败:', e);
                    if (!ignoreError) Vue.prototype.showMsg('数据解析错误');
                    return reject({ code: 500, msg: 'JSON解析失败' });
                }

                // 竞态检查
                if (period && timestamp !== API_TIMESTAMP[url]) {
                    return console.log(`请求结果已刷新，响应被舍弃，url：${url}`);
                }
                console.log('解析后的响应数据:', res.data);
                let { code, msg, data } = res.data || {};

                switch (parseInt(code)) {
                    case 200:
                        resolve(res.data);
                        break;
                    case 401:
                        if (token === getToken()) {
                            // logout();
                        }
                        reject(res.data);
                        break;
                    default:
                        if (ignoreError) return reject(res.data);

                        let { metadata } = data || {};
                        let { delay } = metadata || {};

                        if (delay) {
                            clearTimeout(timer);
                            timer = setTimeout(() => {
                                Vue.prototype.routeBack();
                            }, delay);
                        }

                        if (msg) {
                            Vue.prototype.showMsg(msg);
                        } else {
                            uni.getNetworkType({
                                success: data => {
                                    if (data.networkType === 'none') {
                                        Vue.prototype.showMsg('网络已断开，请检查网络链接');
                                    }
                                }
                            });
                        }
                        reject(res.data || {});
                }
            }
        });
    });
};

export default request;